package serve;

import serve.cnf.Cnf;
import serve.cnf.RegisterMapping;
import serve.controller.IndexController;
import serve.controller.MulController;
import serve.controller.NormalController;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

@WebServlet(name = "Servlet")
public class Servlet extends HttpServlet {


    static {
        try {
            RegisterMapping.register("/index/:uid([0-9]+)", new IndexController());
            RegisterMapping.register("/index/:uid([0-9]+)/:user([a-z|A-Z]+)",new  MulController());
            RegisterMapping.register("/index/123/hello/world",new NormalController());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("hello Get");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
        String reqMethod = req.getMethod();
        String url = req.getRequestURI();
        System.out.println("uri " + url);
        boolean ok = false;

        // 在这里进行动态路由的匹配
        Map<String, String> params = new HashMap<>();
        // 进行正则匹配
        for (Map.Entry<String, Cnf> mp : RegisterMapping.URLMapping.entrySet()) {

            Cnf cnf = mp.getValue();
            Matcher matcher = cnf.pattern.matcher(url);
            if (!matcher.find()) {
                // System.out.println("无法匹配..."+ url);
                continue;
            }

            if (!matcher.group().equals(url)) {
                //  System.out.println("pass "+" 长度不匹配 "+ url);
                continue;
            }

            //System.out.println("长度匹配, " + matcher.group() + "    url is " + url + " count  " + matcher.groupCount());


            for (int i = 0; i < matcher.groupCount(); i++) {
                // System.out.println("find " + i + " value " + matcher.group(i + 1));
                params.put(cnf.params.get(i), matcher.group(i + 1));
            }
            // System.out.println("f*ck " + matcher.group(2) + " count " + matcher.groupCount() + params);

            try {
               // Class<?> clazz = Class.forName(cnf.classPath);
                Class<?> clazz = cnf.clazz;

                Object o = clazz.newInstance();
                // 写...
                Method init = clazz.getDeclaredMethod("Init", javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class, Map.class);

                init.invoke(o, req, resp, params);

                if (reqMethod.equals("GET")) {
                    Method method = clazz.getDeclaredMethod("Get");
                    method.invoke(o);

                } else if (reqMethod.equals("POST")) {
                    Method method = clazz.getDeclaredMethod("Post");
                    method.invoke(o);

                } else if (reqMethod.equals("DELETE")) {
                    Method method = clazz.getDeclaredMethod("Delete");
                    method.invoke(o);

                } else if (reqMethod.equals("PUT")) {

                    Method method = clazz.getDeclaredMethod("Put");
                    method.invoke(o);
                } else if (reqMethod.equals("HEAD")) {
                    Method method = clazz.getDeclaredMethod("Head");
                    method.invoke(o);

                } else if (reqMethod.equals("TRACE")) {
                    Method method = clazz.getDeclaredMethod("Trace");
                    method.invoke(o);

                } else if (reqMethod.equals("OPTIONS")) {
                    Method method = clazz.getDeclaredMethod("Options");
                    method.invoke(o);
                } else if (reqMethod.equals("PATCH")) {
                    Method method = clazz.getDeclaredMethod("Patch");
                    method.invoke(o);
                } else if (reqMethod.equals("MOVE")) {
                    Method method = clazz.getDeclaredMethod("Move");
                    method.invoke(o);
                } else if (reqMethod.equals("LINK")) {
                    Method method = clazz.getDeclaredMethod("Link");
                    method.invoke(o);
                } else if (reqMethod.equals("UNLINK")) {
                    Method method = clazz.getDeclaredMethod("Unlink");
                    method.invoke(o);
                }

                Method method = clazz.getDeclaredMethod("Finish");
                method.invoke(o);
                ok = true;

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (!ok) {
            resp.setStatus(404);

        }

    }


}
